﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace Sizebox.CharacterEditor
{
	// Token: 0x02000260 RID: 608
	[RequireComponent(typeof(Animator))]
	[RequireComponent(typeof(CharacterEditor))]
	public class SkeletonEdit : MonoBehaviour
	{
		// Token: 0x17000191 RID: 401
		// (get) Token: 0x06000D78 RID: 3448 RVA: 0x0006A3ED File Offset: 0x000685ED
		// (set) Token: 0x06000D79 RID: 3449 RVA: 0x0006A3F5 File Offset: 0x000685F5
		public SkeletonEditSkeleton Skeleton { get; private set; }

		// Token: 0x17000192 RID: 402
		// (get) Token: 0x06000D7A RID: 3450 RVA: 0x0006A3FE File Offset: 0x000685FE
		public List<EditBone> SkeletonBones
		{
			get
			{
				return this.Skeleton.Bones;
			}
		}

		// Token: 0x17000193 RID: 403
		// (get) Token: 0x06000D7B RID: 3451 RVA: 0x0006A40B File Offset: 0x0006860B
		// (set) Token: 0x06000D7C RID: 3452 RVA: 0x0006A413 File Offset: 0x00068613
		public Dictionary<string, EditBone> BoneMap { get; private set; }

		// Token: 0x17000194 RID: 404
		// (get) Token: 0x06000D7D RID: 3453 RVA: 0x0006A41C File Offset: 0x0006861C
		// (set) Token: 0x06000D7E RID: 3454 RVA: 0x0006A424 File Offset: 0x00068624
		public Dictionary<EditBone, string> KeyMap { get; private set; }

		// Token: 0x06000D7F RID: 3455 RVA: 0x0006A430 File Offset: 0x00068630
		private void Awake()
		{
			this.Editor = base.GetComponent<CharacterEditor>();
			this.skeletonBonePrefab = (Resources.Load("SkeletonEdit/Bone") as GameObject).GetComponent<EditBone>();
			this.BoneMap = new Dictionary<string, EditBone>();
			this.KeyMap = new Dictionary<EditBone, string>();
			this.CreateBones();
			this.Skeleton = new SkeletonEditSkeleton();
			this.Skeleton.Initialize(this.Editor.Animator);
			if (!this.LoadConfigDataFromFile())
			{
				this.configData = new SkeletonEditConfigData();
				this.Skeleton.GeneratePairings(this);
				this.ApplyConfig(this.configData);
			}
		}

		// Token: 0x06000D80 RID: 3456 RVA: 0x0006A4D0 File Offset: 0x000686D0
		public void SaveConfig()
		{
			string filePath = this.Editor.FolderPath + this.Editor.FolderName + ".skeletondata";
			this.SaveConfigFile(filePath, this.configData);
		}

		// Token: 0x06000D81 RID: 3457 RVA: 0x0006A50C File Offset: 0x0006870C
		private void SaveConfigFile(string filePath, SkeletonEditConfigData data)
		{
			TextWriter textWriter = new StreamWriter(filePath);
			string value = JsonUtility.ToJson(data);
			textWriter.Write(value);
			textWriter.Close();
		}

		// Token: 0x06000D82 RID: 3458 RVA: 0x0006A534 File Offset: 0x00068734
		public bool LoadConfigDataFromFile()
		{
			string folderPath = this.Editor.FolderPath;
			if (!Directory.Exists(folderPath))
			{
				Directory.CreateDirectory(folderPath);
			}
			string text = folderPath + this.Editor.FolderName + ".skeletondata";
			if (File.Exists(text))
			{
				try
				{
					this.configData = this.LoadConfigFile(text);
					this.ApplyConfig(this.configData);
					return true;
				}
				catch
				{
					return false;
				}
				return false;
			}
			return false;
		}

		// Token: 0x06000D83 RID: 3459 RVA: 0x0006A5BC File Offset: 0x000687BC
		private SkeletonEditConfigData LoadConfigFile(string filePath)
		{
			if (File.Exists(filePath))
			{
				string json = File.ReadAllText(filePath);
				return JsonUtility.FromJson<SkeletonEditConfigData>(json);
			}
			return new SkeletonEditConfigData();
		}

		// Token: 0x06000D84 RID: 3460 RVA: 0x0006A5E8 File Offset: 0x000687E8
		public void ApplyConfig(SkeletonEditConfigData data)
		{
			if (data == null)
			{
				return;
			}
			this.ClearAllBoneSiblingData();
			foreach (KeyPair keyPair in data.siblings)
			{
				if (this.BoneMap.ContainsKey(keyPair.key) && this.BoneMap.ContainsKey(keyPair.key2))
				{
					EditBone editBone = this.BoneMap[keyPair.key];
					EditBone editBone2 = this.BoneMap[keyPair.key2];
					editBone.SetSibling(editBone2);
					editBone2.SetSibling(editBone);
				}
			}
		}

		// Token: 0x06000D85 RID: 3461 RVA: 0x0006A6AC File Offset: 0x000688AC
		private void ClearAllBoneSiblingData()
		{
			foreach (EditBone editBone in this.BoneMap.Values)
			{
				editBone.SetSibling(null);
			}
		}

		// Token: 0x06000D86 RID: 3462 RVA: 0x0006A710 File Offset: 0x00068910
		private void CreateBones()
		{
			this.BoneMap.Clear();
			this.KeyMap.Clear();
			foreach (Transform inTransform in this.Editor.Transforms)
			{
				this.CreateBone(inTransform);
			}
		}

		// Token: 0x06000D87 RID: 3463 RVA: 0x0006A788 File Offset: 0x00068988
		private void CreateBone(Transform inTransform)
		{
			string transformKey = this.Editor.GetTransformKey(inTransform);
			if (transformKey == null)
			{
				return;
			}
			EditBone componentInParent = inTransform.GetComponentInParent<EditBone>();
			EditBone editBone = UnityEngine.Object.Instantiate<EditBone>(this.skeletonBonePrefab);
			editBone.Initialize(transformKey, this, inTransform, componentInParent);
			if (!this.BoneMap.ContainsKey(transformKey))
			{
				this.BoneMap.Add(transformKey, editBone);
			}
			if (!this.KeyMap.ContainsKey(editBone))
			{
				this.KeyMap.Add(editBone, transformKey);
			}
		}

		// Token: 0x06000D88 RID: 3464 RVA: 0x0006A804 File Offset: 0x00068A04
		public void CreateBone(Transform inTransform, EditBone parent)
		{
			string transformKey = this.Editor.GetTransformKey(inTransform);
			if (transformKey == null)
			{
				return;
			}
			EditBone editBone = UnityEngine.Object.Instantiate<EditBone>(this.skeletonBonePrefab);
			editBone.Initialize(transformKey, this, inTransform, parent);
			inTransform.localPosition = Vector3.zero;
			inTransform.localRotation = Quaternion.identity;
			inTransform.localScale = Vector3.one;
			if (!this.BoneMap.ContainsKey(transformKey))
			{
				this.BoneMap.Add(transformKey, editBone);
			}
			if (!this.KeyMap.ContainsKey(editBone))
			{
				this.KeyMap.Add(editBone, transformKey);
			}
		}

		// Token: 0x06000D89 RID: 3465 RVA: 0x0006A89C File Offset: 0x00068A9C
		public void Enable()
		{
			foreach (EditBone editBone in this.BoneMap.Values)
			{
				editBone.Enable();
			}
			if (this.Skeleton.hips)
			{
				this.Skeleton.hips.UpdateTransformationRecursive();
			}
			else
			{
				EditBone componentInChildren = base.GetComponentInChildren<EditBone>();
				if (componentInChildren)
				{
					componentInChildren.UpdateTransformationRecursive();
				}
			}
		}

		// Token: 0x06000D8A RID: 3466 RVA: 0x0006A940 File Offset: 0x00068B40
		public void Disable()
		{
			foreach (EditBone editBone in this.BoneMap.Values)
			{
				editBone.Disable();
			}
		}

		// Token: 0x06000D8B RID: 3467 RVA: 0x0006A9A0 File Offset: 0x00068BA0
		public EditBone GetBone(string key)
		{
			if (this.BoneMap.ContainsKey(key))
			{
				return this.BoneMap[key];
			}
			return null;
		}

		// Token: 0x06000D8C RID: 3468 RVA: 0x0006A9C4 File Offset: 0x00068BC4
		public EditBone GetBone(SkeletonEditBones bone)
		{
			SkeletonEditSkeleton skeleton = this.Skeleton;
			switch (bone)
			{
			case SkeletonEditBones.None:
				return null;
			case SkeletonEditBones.Head:
				return skeleton.head;
			case SkeletonEditBones.Neck:
				return skeleton.neck;
			case SkeletonEditBones.UpperSpine:
				return skeleton.upperSpine;
			case SkeletonEditBones.MidSpine:
				return skeleton.midSpine;
			case SkeletonEditBones.LowerSpine:
				return skeleton.lowerSpine;
			case SkeletonEditBones.Hips:
				return skeleton.hips;
			case SkeletonEditBones.LeftUpperArm:
				return skeleton.leftUpperArm;
			case SkeletonEditBones.LeftLowerArm:
				return skeleton.leftLowerArm;
			case SkeletonEditBones.LeftHand:
				return skeleton.leftHand;
			case SkeletonEditBones.RightUpperArm:
				return skeleton.rightUpperArm;
			case SkeletonEditBones.RightLowerArm:
				return skeleton.rightLowerArm;
			case SkeletonEditBones.RightHand:
				return skeleton.rightHand;
			case SkeletonEditBones.LeftUpperLeg:
				return skeleton.leftUpperLeg;
			case SkeletonEditBones.LeftLowerLeg:
				return skeleton.leftLowerLeg;
			case SkeletonEditBones.LeftFoot:
				return skeleton.leftFoot;
			case SkeletonEditBones.RightUpperLeg:
				return skeleton.rightUpperLeg;
			case SkeletonEditBones.RightLowerLeg:
				return skeleton.rightLowerLeg;
			case SkeletonEditBones.RightFoot:
				return skeleton.rightFoot;
			case SkeletonEditBones.LeftBreast:
				return skeleton.leftBreast;
			case SkeletonEditBones.RightBreast:
				return skeleton.rightBreast;
			case SkeletonEditBones.LeftShoulder:
				return skeleton.leftShoulder;
			case SkeletonEditBones.RightShoulder:
				return skeleton.rightShoulder;
			default:
				return null;
			}
		}

		// Token: 0x06000D8D RID: 3469 RVA: 0x0006AADC File Offset: 0x00068CDC
		public static List<EditBone> FindFirstChildEditBones(Transform bone)
		{
			List<EditBone> result = new List<EditBone>();
			for (int i = 0; i < bone.transform.childCount; i++)
			{
				SkeletonEdit.FindFirstChildBonesLoop(bone.transform.GetChild(i), ref result);
			}
			return result;
		}

		// Token: 0x06000D8E RID: 3470 RVA: 0x0006AB20 File Offset: 0x00068D20
		private static void FindFirstChildBonesLoop(Transform transform, ref List<EditBone> childBones)
		{
			EditBone component = transform.GetComponent<EditBone>();
			if (component)
			{
				childBones.Add(component);
				return;
			}
			for (int i = 0; i < transform.childCount; i++)
			{
				SkeletonEdit.FindFirstChildBonesLoop(transform.GetChild(i), ref childBones);
			}
		}

		// Token: 0x06000D8F RID: 3471 RVA: 0x0006AB6C File Offset: 0x00068D6C
		public void LoadPreset(SkeletonPresetData preset, string dataId)
		{
			foreach (EditBone editBone in this.BoneMap.Values)
			{
				editBone.SetData(dataId, BoneTransformData.Default);
			}
			if (preset.hashCode.Equals(this.Editor.SkeletonHashCode))
			{
				foreach (BoneData boneData2 in preset.boneData)
				{
					if (this.BoneMap.ContainsKey(boneData2.key))
					{
						this.BoneMap[boneData2.key].SetData(dataId, boneData2.data);
					}
				}
			}
			else
			{
				Debug.Log("Using generic loading!");
				Dictionary<string, BoneTransformData> dictionary = new Dictionary<string, BoneTransformData>();
				foreach (BoneData boneData4 in preset.boneData)
				{
					dictionary.Add(boneData4.key, boneData4.data);
				}
				foreach (SkeletonDataMap skeletonDataMap in preset.skeletonMap)
				{
					string key = skeletonDataMap.key;
					if (dictionary.ContainsKey(key))
					{
						this.Skeleton.SetData(skeletonDataMap.bone, dataId, dictionary[key]);
					}
				}
			}
		}

		// Token: 0x06000D90 RID: 3472 RVA: 0x0006AD18 File Offset: 0x00068F18
		public void CreatePair(string key, string key2)
		{
			EditBone bone = null;
			EditBone bone2 = null;
			if (this.BoneMap.ContainsKey(key))
			{
				bone = this.BoneMap[key];
			}
			if (this.BoneMap.ContainsKey(key2))
			{
				bone2 = this.BoneMap[key2];
			}
			this.CreatePair(bone, bone2);
		}

		// Token: 0x06000D91 RID: 3473 RVA: 0x0006AD70 File Offset: 0x00068F70
		public void CreatePair(EditBone bone, EditBone bone2)
		{
			if (!bone || !bone2)
			{
				return;
			}
			bone.SetSibling(bone2);
			bone2.SetSibling(bone);
			string key = bone.Key;
			string key2 = bone2.Key;
			KeyPair pair = new KeyPair(key, key2);
			this.configData.AddPair(pair);
		}

		// Token: 0x06000D92 RID: 3474 RVA: 0x0006ADC8 File Offset: 0x00068FC8
		public void RemovePair(string key, string key2)
		{
			EditBone bone = null;
			EditBone bone2 = null;
			if (this.BoneMap.ContainsKey(key))
			{
				bone = this.BoneMap[key];
			}
			if (this.BoneMap.ContainsKey(key2))
			{
				bone2 = this.BoneMap[key2];
			}
			this.RemovePair(bone, bone2);
		}

		// Token: 0x06000D93 RID: 3475 RVA: 0x0006AE20 File Offset: 0x00069020
		public void RemovePair(EditBone bone, EditBone bone2)
		{
			if (!bone || !bone2)
			{
				return;
			}
			bone.SetSibling(null);
			bone2.SetSibling(null);
			string key = bone.Key;
			string key2 = bone2.Key;
			KeyPair pair = new KeyPair(key, key2);
			this.configData.RemovePair(pair);
		}

		// Token: 0x04001256 RID: 4694
		private CharacterEditor Editor;

		// Token: 0x04001257 RID: 4695
		private EditBone skeletonBonePrefab;

		// Token: 0x0400125B RID: 4699
		private SkeletonEditConfigData configData = new SkeletonEditConfigData();

		// Token: 0x0400125C RID: 4700
		private const string FILE_EXTENSION = ".skeletondata";
	}
}
